/**
 * WebController.java 
 * Copyright © 2015-3015, 杭州泊享网络科技有限公司
 * 
 * @author Liu Tao
 * @create 2014年8月16日
 */
package com.pshare.framework.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.pshare.base.bean.SeaxResponse;
import com.pshare.constant.ReturnCode;
import com.pshare.constant.SeaxConstants;
import com.pshare.enums.CodeMsg;
import com.pshare.framework.exception.NoLoginException;
import com.pshare.framework.exception.SeaxRuntimeException;
import com.pshare.tool.SessionTool;

/**
 * Web界面的Controller基类
 */
@Controller
public class WebController {

	protected static final Logger logger = Logger.getLogger(WebController.class);

	protected static final String TEMPLATE = SeaxConstants.KEY_VIEW_NAME;
	protected static final String PAGE_CONTENT = SeaxConstants.KEY_PAGE_CONTENT;

	@ExceptionHandler(NoLoginException.class)
	public String handleNoLoginException(HttpServletRequest request, HttpServletResponse response) {
		String originalUrl = request.getServletPath();
		/*String queryStr = request.getQueryString();
		if (StringUtils.isNotBlank(queryStr)) {
			originalUrl += "?" + queryStr;
		}
		SessionTool.setAttribute(SeaxConstants.URL_ORIGINAL, originalUrl);*/
		return SeaxConstants.URL_REDIRECT + SeaxConstants.URL_LOGIN_ACTION+"?originalUrl="+originalUrl;
	}

	/**
	 * 处理一般异常
	 * 
	 * @param ex
	 * @return SeaxResponse
	 */
	@ExceptionHandler(Exception.class)
	public SeaxResponse handleException(Exception ex,HttpServletRequest request, HttpServletResponse response) {
		String errMsg = "";
		if (ex instanceof org.springframework.web.multipart.MaxUploadSizeExceededException) {
			errMsg = "上传文件太大";
		} else {
			errMsg = ex.getMessage();
		}
		String requestType = request.getHeader("X-Requested-With");  
		if(requestType != null){
			try {
				logger.error(errMsg, ex);
				response.getWriter().println(JSONObject.fromObject(failed("系统繁忙")).toString());
				return null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		logger.error(errMsg, ex);
		return failed("系统繁忙");
	}

	/**
	 * 处理自定义运行时异常
	 * 
	 * @param ex
	 * @param request
	 * @return
	 */
	@ExceptionHandler(SeaxRuntimeException.class)
	public String handleException(SeaxRuntimeException ex, HttpServletRequest request, HttpServletResponse responese) {
		String requestType = request.getHeader("X-Requested-With");  
		if(requestType != null){
			try {
				responese.setCharacterEncoding("UTF-8");
				responese.getWriter().println(JSONObject.fromObject(failed(ex.getMessage())).toString());
				return null;
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
		}
		FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
		if (outputFlashMap != null) {
			outputFlashMap.put(SeaxConstants.PAGE_KEY_ERROR, ex.getMessage());
		}
		
		// 请求来源页
		String originUrl = request.getHeader("Referer");
		if (StringUtils.isBlank(originUrl)) {
			return null;
		}
		return SeaxConstants.URL_REDIRECT + originUrl;
	}
	
	protected String getErrorsMessage(BindingResult result) {
		String message = "";
		List<ObjectError> list = result.getAllErrors();
		for (ObjectError objectError : list) {
			message = message + objectError.getDefaultMessage() + ";";
		}
		if (message.length() > 0) {
			message = message.substring(0, message.length() - 1);
		}
		return message;
	}

	protected SeaxResponse succeed() {
		return getResult(true, null, "");
	}

	protected SeaxResponse succeed(Object ojbect) {
		return getResult(true, ojbect, "");
	}

	protected SeaxResponse succeed(String key, Object object) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put(key, object);
		return succeed(result);
	}

	protected SeaxResponse failed() {
		return getResult(false, "");
	}

	protected SeaxResponse failed(String message) {
		return getResult(false, message);
	}

	protected SeaxResponse failed(List<FieldError> errors) {
		return getResult(false, errors);
	}

	protected SeaxResponse failed(boolean status, String message) {
		return getResult(status, message);
	}

	public static SeaxResponse getResult(boolean status, String message) {
		return getResponseData(status, null, message);
	}

	public static SeaxResponse getResult(boolean status, Object data, String message) {
		return getResponseData(status, data, message);
	}

	public static SeaxResponse getResult(boolean status, List<FieldError> errors) {
		return getResponseData(status, null, null, errors);
	}

	private static SeaxResponse getResponseData(boolean status, Object data, String message) {
		return getResponseData(status, data, message, null);
	}

	private static SeaxResponse getResponseData(boolean status, Object data, String message, List<FieldError> errors) {
		SeaxResponse obj = new SeaxResponse();
		obj.setStatus(status);
		if (!status) {
			obj.setCode(ReturnCode.BIZ_ERROR);
		}
		obj.setData(data);
		obj.setMsg(message);
		if (errors != null) {
			for (FieldError error : errors) {
				obj.addError(error);
			}
		}

		return obj;
	}
	
}
